package com.wushijia.java8.time;

import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
import static java.time.temporal.TemporalAdjusters.nextOrSame;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
import java.util.TimeZone;

/**
 * description:java8中提供了一些时间上的新类，如LocalDate,LocalTime,Instant,Duration,Period LocalDate的实例对象是一个不可变类
 *
 * 这些日期-时间对象都是不可修改的，这是为了更好地支持函数式编程，确保线程安全，保持领域模式一致性而做出的重大设计决定
 *
 * @author yang
 * @date 2018/5/30 20:24
 */
public class LocalDateTimeDemo02 {

  public static void main(String[] args) {
    LocalDate date = LocalDate.of(2018, 05, 30);
    System.out.println(date.getYear() + "年" + date.getMonth().getValue() + "月" + date.getDayOfMonth() + "日" + "；星期：" + date.getDayOfWeek());
    System.out.println(
        date.get(ChronoField.YEAR) + "年" + date.get(ChronoField.MONTH_OF_YEAR) + "月" + date.get(ChronoField.DAY_OF_MONTH) + "日" + "；星期：" + date
            .get(ChronoField.DAY_OF_WEEK));
    System.out.println("今年是闰年吗：" + date.isLeapYear() + "；本月有" + date.lengthOfMonth() + "天");
    LocalDate now = LocalDate.now();//当前时间

    LocalTime time = LocalTime.of(20, 40, 33);
    System.out.println(time.getHour() + "时" + time.getMinute() + "分" + time.getSecond() + "秒");

    LocalDate localDate = LocalDate.parse("2018-05-30");
    LocalTime localTime = LocalTime.parse("20:42:44");
    System.out.println(localTime.getHour() + "时" + localTime.getMinute() + "分" + localTime.getSecond() + "秒");
    System.out.println(
        localTime.get(ChronoField.HOUR_OF_DAY) + "时" + localTime.get(ChronoField.MINUTE_OF_HOUR) + "分" + localTime.get(ChronoField.SECOND_OF_MINUTE)
            + "秒");

    //LocalDateTime,可合并日期和时间,也可分割提取日期和时间
    LocalDateTime dt1 = LocalDateTime.of(2018, 05, 30, 20, 45, 33);
    LocalDateTime dt2 = LocalDateTime.of(localDate, localTime);
    LocalDateTime dt3 = localDate.atTime(localTime);
    LocalDateTime dt4 = localTime.atDate(localDate);

    LocalDate localDate1 = dt1.toLocalDate();
    LocalTime lcoalTime1 = dt1.toLocalTime();

    Instant instant = Instant.ofEpochSecond(3);
    //instant.get(ChronoField.DAY_OF_MONTH);错误，需使用Duration和Period
    //比较两个LocalTIme和LocalDateTime
    Duration d1 = Duration.between(dt1, dt2);
    System.out.println(d1.toMinutes());
    Duration d2 = Duration.of(3, ChronoUnit.MINUTES);
    Duration d3 = Duration.ofMinutes(3);
    System.out.println(d3.toMinutes());
    //比较两个LocalDate
    Period period = Period.between(localDate1, localDate);
    System.out.println(period.getDays());
    Period p2 = Period.ofDays(10);
    Period p3 = Period.of(2, 3, 1);

    //操作日期-时间
    date = date.with(ChronoField.MONTH_OF_YEAR, 06);
    date = date.plusYears(1).minusDays(10);
    date.withYear(2017);//为赋值，不会产生新日期，因为LocaDate是不可变类
    System.out.println(date.getYear() + "年" + date.getMonth().getValue() + "月" + date.getDayOfMonth() + "日" + "；星期：" + date.getDayOfWeek());

    LocalDate date1 = localDate.with(lastDayOfMonth());
    System.out.println(date1.getYear() + "年" + date1.getMonth().getValue() + "月" + date1.getDayOfMonth() + "日" + "；星期：" + date1.getDayOfWeek());
    LocalDate date2 = localDate.with(nextOrSame(DayOfWeek.FRIDAY));
    System.out.println(date2.getYear() + "年" + date2.getMonth().getValue() + "月" + date2.getDayOfMonth() + "日" + "；星期：" + date2.getDayOfWeek());

    String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
    System.out.println(s1);
    String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
    System.out.println(s2);

    //DateTimeFormatter是线程安全的,可以如下使用单例模式生成实例
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    LocalDate localDate2 = LocalDate.parse("20180531", DateTimeFormatter.BASIC_ISO_DATE);
    System.out.println(
        localDate2.getYear() + "年" + localDate2.getMonth().getValue() + "月" + localDate2.getDayOfMonth() + "日" + "；星期：" + localDate2.getDayOfWeek());

    String s3 = localDate2.format(dateTimeFormatter);
    System.out.println(s3);
    LocalDate localDate3 = LocalDate.parse(s3, dateTimeFormatter);

    //自定义日期格式器，更精细的控制：DateTimeFormatterBuilder
    DateTimeFormatter chinaFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日", Locale.CHINA);
    String s4 = localDate3.format(chinaFormatter);
    System.out.println(s4);

    //时区
    ZoneId shZone = ZoneId.of("Asia/Shanghai");
    ZoneId zoneId = TimeZone.getDefault().toZoneId(); //==ZoneId.systemDefault();

    //ZonedDateTime包括LocalDate+LocalTIme+ZoneId
    ZonedDateTime zonedDateTime = localDate3.atStartOfDay(shZone);
    ZonedDateTime zonedDateTime1 = dt1.atZone(zoneId);

    //转到其他时区
    ZonedDateTime zonedDateTime2 = ZonedDateTime.now().withZoneSameInstant(ZoneId.of("Europe/Paris"));
    System.out.println(zonedDateTime2);

    LocalDateTime localDateTime = LocalDateTime.ofInstant(zonedDateTime2.toInstant(), shZone);
    System.out.println(localDateTime);

    //相对于伦敦格林尼治时间偏差5个小时
    ZoneOffset newYorkOffset = ZoneOffset.of("-05:00");
    OffsetDateTime dateTimeInNewYork = OffsetDateTime.of(localDateTime, newYorkOffset);
    System.out.println(dateTimeInNewYork);
  }
}
